Control de calidad de la velocidad

Author

Mariana Morales

1 Código

Este código fue creado utilizando Rstudio version 2024.12.1 mediante la creación de un documeto quarto.

# Cargar librerías
library(dplyr)
library(lubridate)
library(ggplot2)
library(readr)
library(plotly)
library(zoo)
# Cargar los archivos
datos <- read.table("C:\\Users\\marin\\Documents\\Trabajo\\Dayos Guillaume\\Rstudio quarto\\Datos sensores3.csv", sep = ";", dec = ",", header = TRUE)

# Convertir a numeros
datos$Vitesse <- as.numeric(datos$Vitesse)
datos$VEGA_E <- as.numeric(datos$VEGA_E)
# Guardamos los valores originales para comparar
datos$Vitesse_original <- datos$Vitesse  # o guardalo antes de aplicar filtros si querés ver el cambio real
# Convertir VEGA_E a numérico, reemplazando comas por puntos
datos <- datos %>% mutate(VEGA_E = as.numeric(gsub(",", ".", VEGA_E)))

1.1 Filtro de valores repetidos

Si hay más de tres valores repetidos consecutivos se cambiará el valor al código NaN

# Detectar secuencias de valores consecutivos iguales
rle_vitesse <- rle(datos$Vitesse)

# Crear un vector lógico con TRUE en las posiciones que deben ser reemplazadas por NaN
to_replace <- inverse.rle(with(rle_vitesse, {
  list(lengths = lengths, values = lengths > 3)
}))

# Reemplazar esos valores por NaN
datos$Vitesse[to_replace] <- NaN

1.2 Filtro de outliers

Para esto lo mejor es usar una media móvil, se tomó en cuenta la resolución temporal por lo que el tamaño de la media móvil será de 4 mediciones (40 minutos). Si la diferencia entre el valor y la media móvil es mayor a un 30% entonces se consideran como outliers.

# Asegurate que vitesse sea numérico
datos$Vitesse <- as.numeric(datos$Vitesse)

# Calcular la media móvil con ventana de 3
media_movil <- zoo::rollapply(datos$Vitesse, width = 4, FUN = mean, align = "center", fill = NA)

# Calcular el porcentaje de diferencia
diferencia_relativa <- abs(datos$Vitesse - media_movil) / media_movil

# Marcar como outliers los valores con más de 30% de diferencia
outliers <- diferencia_relativa > 0.3

# Reemplazar por NaN
datos$Vitesse[outliers] <- NaN

2 Filtro para los límites físicos

La velocidad máxima en superficie de un río natural es de 7 m/s y el límite mínimo recomendado es el 0.02 m/s, todo lo que esté fuera de este rango se colocará como NaN.

# Aplicar el filtro y asignar NaN a los valores fuera de rango
datos$Vitesse[datos$Vitesse < 20 | datos$Vitesse > 7000] <- NaN

3 Filtro para el SNR

Los datos con un valor de SNR inferior a 10 dBm pueden no ser precisos y los que se encuentran menores a 6 no son confiables.

# Asegurate que vitesse sea numérico
datos$SNR_avg <- as.numeric(datos$SNR_avg)

# Filtrar y asignar NaN a la variable 'Vitesse' cuando 'SNR' es menor a 10
datos$Vitesse[datos$SNR_avg < 10] <- NaN

# Verifica el cambio en los datos
summary(datos$Vitesse)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
  365.0   632.0   694.0   761.8   892.0  5198.0   20328 
# Guardar el resultado final con ; como separador
write_delim(datos, "datos_velocidad_filtrados.csv", delim = ",")

4 Gráfico de velocidad

# Cargar los archivos
filtrados <- read_delim("datos_velocidad_filtrados.csv", delim = ",", col_types = cols(.default = "c"))

#Eliminar filas con datos NaN
#datos_sin_NaN <- drop_na(datos)

#Convertir DateTime a tipo fecha
datos$DateTime <- as.POSIXct(datos$DateTime, format = "%d/%m/%Y %H:%M")
# Crear la gráfica interactiva
fig <- plot_ly()

fig <- fig %>% add_markers(
  x = datos$DateTime, 
  y = datos$Vitesse_original, 
  name = "Vitesse original",
  marker = list(
    color = "gray",
    size = 3
  ),
  visible = "legendonly"
)

fig <- fig %>% add_markers(
  x = datos$DateTime, 
  y = datos$Vitesse, 
  name = "Vitesse",
  marker = list(
    color = "blue", 
    size = 3
  )
)

fig <- fig %>% layout(
  title = "Quality Control: Filtered Vitesse and original Vitesse",
  xaxis = list(title = "Fecha", type = "date"),
  yaxis = list(
    title = "VEGA_E",
    side = "left",
    showgrid = FALSE
  ),
  yaxis2 = list(
    side = "right",
    overlaying = "y",
    showgrid = TRUE,
    title_standoff = 30,  # Ajustar la distancia entre el título y el eje
    ticklen = 6,          # Ajustar la longitud de las marcas de los ticks
    tickangle = 0         # Ajustar el ángulo
  ),
  legend = list(
    orientation = "h",     # horizontal
    x = 0,                 # alineado a la izquierda
    y = -0.2               # debajo del eje X
  ),
  hovermode = "x",
  width = 800,
  height = 450,
  margin = list(r = 100)  # Ajustar el margen derecho para dar espacio al eje secundario
)

# Mostrar la gráfica interactiva
fig

5 Gráfico de velocidad vs Nivel

# Crear un nuevo data frame sin valores NA/NaN
df <- na.omit(datos[, c("DateTime", "VEGA_E", "Vitesse")])
y_max <- max(df$VEGA_E)

# Crear el gráfico interactivo
fig <- plot_ly(
  data = df,
  x = ~VEGA_E,
  y = ~Vitesse,
  type = 'scatter',
  mode = 'markers',
  marker = list(color = 'darkblue', size = 6),
  text = ~paste("Fecha:", DateTime, "<br>VEGA_E:", VEGA_E, "<br>Vitesse:", Vitesse),
  hoverinfo = 'text',
  name = "Vitesse filtrada vs VEGA_E"
)

# Personalizar diseño
fig <- fig %>% layout(
  title = "Relación entre VEGA_E y Vitesse filtrada (sin NaN)",
  xaxis = list(title = "VEGA_E"),
  yaxis = list(title = "Vitesse filtrada (m/s)"),
  hovermode = "closest"
)

# Mostrar gráfico
fig